package pl.mchaniewski.ryneczek.scheduler.task;

import java.util.Date;
import java.util.List;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import pl.mchaniewski.ryneczek.dao.CompanyDao;
import pl.mchaniewski.ryneczek.dao.QuotationDao;
import pl.mchaniewski.ryneczek.pojo.Company;
import pl.mchaniewski.ryneczek.pojo.Quotation;
import pl.mchaniewski.ryneczek.screenscrapping.ContinuousTrading;
import pl.mchaniewski.ryneczek.utilities.DateUtil;

import com.sun.el.parser.ParseException;

@Component("currentQuotationRefresher")
public class CurrentQuotationRefresher {
    private static final Logger logger = LoggerFactory
            .getLogger(CurrentQuotationRefresher.class);
    private QuotationDao quotationDao;
    private CompanyDao companyDao;
    private ContinuousTrading continuousScrapper;

    @Autowired
    public void setQuotationDao(QuotationDao quotationDao) {
        this.quotationDao = quotationDao;
    }

    @Autowired
    public void setCompanyDao(CompanyDao companyDao) {
        this.companyDao = companyDao;
    }

    @Autowired
    public void setContinuousScrapper(ContinuousTrading continuousScrapper) {
        this.continuousScrapper = continuousScrapper;
    }

    public void run() throws Exception {
        Map<String, Quotation> quotationMap = null;

        try {
            quotationMap = continuousScrapper.getAll();
        } catch (Exception ex) {
            logger.warn("Scrapper threw exception: {} Stack trace: {}",
                    ex.getMessage(), ex.getStackTrace());
        }

        if (quotationMap == null || quotationMap.size() == 0) {
            logger.warn("Task couldn't update continuous trading quotations. List was empty.");

            throw new ParseException("Parser returned empty list.");
        } else {
            List<Company> allCompanies = companyDao.loadAll();

            if (logger.isDebugEnabled()) {
                logger.debug("[START] Marking all companies as not updated.");
            }
            for (Company c : allCompanies) {
                c.setWasInLastUpdate(false);
                companyDao.save(c);
            }
            if (logger.isDebugEnabled()) {
                logger.debug("[STOP] Finnished marking all companies.");
            }

            for (Map.Entry<String, Quotation> entry : quotationMap.entrySet()) {
                if (!DateUtil.isDateAfterWhen(DateUtil.getNow(), entry
                        .getValue().getListingDate())) {
                    if (logger.isDebugEnabled()) {
                        logger.debug(
                                "Quotation is from yesterday. Listing date: {} Now: {}",
                                entry.getValue().getListingDate(),
                                DateUtil.getNow());
                    }

                    continue;
                }

                List<Company> company = companyDao.findByName(entry.getKey());

                Company tempComp = null;

                if (company == null || company.size() == 0) {
                    tempComp = new Company();
                    tempComp.setName(entry.getKey());

                    if (logger.isDebugEnabled()) {
                        logger.debug("New company found: {}",
                                tempComp.getName());
                    }
                } else {
                    tempComp = company.get(0);
                    if (logger.isDebugEnabled()) {
                        logger.debug("Old company update.");
                    }
                }

                tempComp.setWasInLastUpdate(true);
                companyDao.save(tempComp);

                tempComp = companyDao.findByName(entry.getKey()).get(0);

                List<Quotation> lastQuotationDate = quotationDao.findLatest(
                        tempComp.getCompanyid(), true);

                if (lastQuotationDate != null && lastQuotationDate.size() > 0) {
                    Date newQuoatationDate = entry.getValue().getListingDate();
                    Date oldQuotationDate = lastQuotationDate.get(0)
                            .getListingDate();

                    boolean isNew = DateUtil.isDateAfterWhen(newQuoatationDate,
                            oldQuotationDate);
                    if (logger.isDebugEnabled()) {
                        logger.debug("New date:{} Old date:{}",
                                newQuoatationDate, oldQuotationDate);
                    }
                    if (!isNew) {
                        if (logger.isDebugEnabled()) {
                            logger.debug("Already have last quotation for {}",
                                    tempComp.getName());
                        }
                        continue;
                    }
                }

                if (logger.isDebugEnabled()) {
                    logger.debug("New quotation for {}", tempComp.getName());
                }
                entry.getValue().setCompany(tempComp);
                quotationDao.save(entry.getValue());
            }
        }
    }
}
